
from hashlib import md5

import xml.etree.cElementTree as ET

import requests

import uuid

class WeChatService(object):

    def __init__(self, merchant_key=None):

        self.merchant_key = merchant_key

    def create_sign(self, pay_data):

        '''
        生成签名
        :param pay_data:
        :return:
        '''
        stringA = '&'.join(["{0}={1}".format(k, pay_data.get(k)) for k in sorted(pay_data)])
        stringSignTemp = "{0}&key={1}".format(stringA, self.merchant_key)

        sign = md5(stringSignTemp.encode('utf-8')).hexdigest()

        return sign.upper()

    def get_pay_info(self, pay_data=None):
        '''
        获取支付信息
        '''
        sign = self.create_sign(pay_data)
        pay_data['sign'] = sign
        xml_data = self.dict_to_xml(pay_data)
        url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
        headers = {
            'Content-Type': 'application/xml'
        }
        r = requests.post(url=url, data=xml_data.encode('utf-8'), headers=headers)
        r.encoding = 'utf-8'
        print(r.text)
        if r.status_code == 200:
            # 将从微信获取到的支付信息构造成，微信小程序支付接口requirepayment需要的参数
            prepay_id = self.xml_to_dict(r.text).get('prepay_id')
            if not prepay_id:
                return False
            '''
            appId       小程序标识id
            nonceStr    随机字符串 长度为32个字符
            package     包含统一下单接口返回的prepay_id，格式为prepay_id=****
            signType    签名算法 固定MD5
            timeStamp   时间戳 当前时间
            
            '''
            pay_sign_data = {
                'appId': pay_data.get('appid'),
                'nonceStr': pay_data.get('nonce_str'),
                'package': 'prepay_id={0}'.format(prepay_id),
                'signType': 'MD5',
                'timeStamp': pay_data['out_trade_no'],
            }
            # 生成签名参数
            pay_sign = self.create_sign(pay_sign_data)
            pay_sign_data.pop('appId')

            pay_sign_data['paySign'] = pay_sign
            pay_sign_data['prepay_id'] = prepay_id

            return pay_sign_data

        return False


    # 字典对象转xml格式数据
    def dict_to_xml(self, dict_data):
        xml = ['<xml>']
        for k, v in dict_data.items():
            xml.append('<{0}>{1}</{0}>'.format(k, v))
        xml.append('</xml>')
        return "".join(xml)

    # xml数据转字典
    def xml_to_dict(self, xml_data):
        xml_dict = {}
        root = ET.fromstring(xml_data)
        for child in root:
            xml_dict[child.tag] = child.text

        return xml_dict

    # 产生一个随机字符
    def get_nonce_str(self):

        return str(uuid.uuid4()).replace('-', '')